package com.ctsi.system.service;

import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.id.IdGen;
import com.ctsi.commons.util.response.Page;
import com.ctsi.framework.mybatis.support.MybatisGenericDao;
import com.ctsi.security.ISecurity;
import com.ctsi.security.domain.RolePermission;
import com.ctsi.system.domain.SysMenus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统菜单 Service 类
 *
 * @author zhangjw
 * @description 系统菜单
 * @created Fri May 04 14:39:10 CST 2018
 */
@Repository
public class SysMenusService {
    private static final Logger logger = LoggerFactory.getLogger(SysMenusService.class);

    @Autowired
    private MybatisGenericDao dao;
    @Autowired
    private ISecurity iSecurity;

    /**
     * 添加
     */
    public void insertSysMenus(SysMenus sysMenus) {
        if (null == sysMenus.getId()) {
            sysMenus.setId(IdGen.get().nextId());
        }
        if (UtilValidate.isEmpty(sysMenus.getMenuType())) {
            sysMenus.setMenuType(SysMenus.DEFAULT_MENU_TYPE);
        }
        logger.debug("insert {}", sysMenus);
        dao.insert(sysMenus);
    }

    /**
     * 动态更新
     */
    public int updateSysMenusByPKSelective(SysMenus sysMenus) {
        logger.debug("updateByPrimaryKeySelective {}", sysMenus);
        return dao.update(SysMenus.class.getName() + ".updateByPrimaryKeySelective", sysMenus);
    }

    /**
     * 更新
     */
    public int updateSysMenus(SysMenus sysMenus) {
        logger.debug("update {}", sysMenus);
        return dao.update(sysMenus);
    }


    public SysMenus editSysMenusById(String id) {
        if (null != id) {
            return null;
        }
        logger.debug("editById {}", id);
        return (SysMenus) dao.queryForObject(SysMenus.class.getName() + ".edit", id);
    }

    /**
     * 根据ID查找 SysMenus对象
     */
    public SysMenus selectSysMenusById(String id) {
        logger.debug("selectSysMenusById {}", id);
        return (SysMenus) dao.queryForObject(SysMenus.class.getName() + ".selectSysMenusById", id);
    }

    /**
     * 删除SysMenus对象
     */
    public int removeSysMenus(String id) {
        if (null != id) {
            return dao.delete(SysMenus.class.getName() + ".delete", id);
        }
        //return dao.remove(id);
        return 0;
    }

    /**
     * 详细页查询
     */
    public Map<String, Object> findByDetail(String id) {
        return (Map<String, Object>) dao.queryForObject(SysMenus.class.getName() + ".findByDetail", id);
    }

    /**
     * 多条件查询结果
     */
    public Page<Map<String, Object>> findByMulitCondition(Map<String, Object> param, int start, int pageSize) {
        logger.debug("findByMulitCondition {}", param);
        if (pageSize < 0 || pageSize > 2000) {
            pageSize = Page.DEFAULT_PAGE_SIZE;
        }
        if (start != -1) {
            return dao.queryPage(SysMenus.class.getName() + ".selectMulitCondition", param, start, pageSize);
        } else {
            throw new RuntimeException("参数不正确 !!");
        }
    }

    /**
     * 多条件查询结果不分页
     */
    public List<?> find(Map<String, Object> map) {
        logger.debug("find {}", map);
        return dao.queryForList(SysMenus.class.getName() + ".selectByMap", map);
    }

    /**
     * 获取所有菜单，控制权限
     *
     * @param userId
     * @param menuId
     * @param menuType
     * @return
     */
    @Deprecated
    public List<SysMenus> getAllMenusByMenuType(String userId, Long menuId, String menuType) {
        return (List<SysMenus>) this.dao.queryForList(SysMenus.class.getName() + ".selectAllMenus", new HashMap<String, Object>() {{
            put("id", menuId);
            put("menuType", menuType);
        }});
    }

    /**
     * 通过parentId获取菜单项
     *
     * @param parentId
     * @return
     */
    public List<SysMenus> getMenusByParentId(String userId, Long parentId, String menuType) {
        //TODO: 处理功能权限
        return (List<SysMenus>) this.dao.queryForList(SysMenus.class.getName() + ".childrenMenus", new HashMap<String, Object>() {{
            put("parentId", parentId);
            put("menuType", menuType);
        }});
    }


    /**
     * 带权限的查询菜单树
     *
     * @param userLoginId
     * @param menuId
     * @param menuType
     * @return
     */
    public List<SysMenus> getAllSysMenusWithPermission(String userLoginId, Long menuId, String menuType) {
        Set<RolePermission> rolePermissions = iSecurity.getPersonRolePermission(userLoginId);
        Set<String> permissions = rolePermissions.stream()
                .map(RolePermission::getPermissionId).collect(Collectors.toSet());
        Map<String, Object> params = new HashMap<>();
//		params.put("id",menuId);
        params.put("menuType", menuType);
        if (UtilValidate.isNotEmpty(permissions)) {
            params.put("permissions", permissions);
        }
        List<SysMenus> result = (List<SysMenus>) this.dao.queryForList(SysMenus.class.getName() + ".selectAllSysMenusWithPermission", params);
        Map<Long, List<SysMenus>> map = result.stream().collect(Collectors.groupingBy(SysMenus::getParentId));
        SysMenus parent = map.get(1L).get(0);
        createTree(parent, map);
        return Arrays.asList(parent);
    }

    private void createTree(SysMenus parent, Map<Long, List<SysMenus>> map) {
        long parentId = parent.getId();
        if (map.get(parentId) != null) {
            map.get(parentId)
                    .stream().filter(x -> x.getParentId() == parentId).sorted(Comparator.comparing(SysMenus::getOrderNum))
                    .forEach(x -> {
                        parent.getChildren().add(x);
                        createTree(x, map);
                    });
        }
    }


}
